/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hue;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Hue
 */
public class OpenURL extends HttpServlet {
    public static String HTTP_REFERER = "http://www.5giay.vn/26-nha-dat-bat-dong-san/1777092-chuyen-nhan-ky-gui-nha-quan-7-moi-gioi-mua-ban-tu-van-phap-ly-nha-dat-quan-7-a-612.html";
    public static String PROXY_HOST;
    public static int PROXY_PORT;

    protected final String SERVER_URL = "http://adf.ly";
    protected final String USER_AGENT = "Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1";
    protected final String COOKIES_IN_SESSION = "COOKIES_IN_SESSION";
    
    @Override
    public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
        try {
            process(request, response);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    @Override
    public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
        try {
            process(request, response);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    protected void process(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setContentType("text/html");
    }
    
    protected void httpGet(HttpServletRequest request, HttpServletResponse response, String url, OutputStream out) {
        try {
            System.out.println(request.getMethod() + " " + url);

            HttpURLConnection connection = getConnection(request, url);

            InputStream in = connection.getInputStream();
            byte[] buff = readData(in);
            out.write(buff);

            List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
            keepCookies(request, cookies);
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
    }
    
    protected void httpPost(HttpServletRequest request, HttpServletResponse response, String url, OutputStream out) throws IOException {
        try {
            System.out.println(request.getMethod() + " " + url);

            HttpURLConnection connection = getConnection(request, url);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            byte[] payload = readData(request.getInputStream());
            System.out.println("payload:" + new String(payload));
            connection.setDoOutput(true);
            OutputStream output = null;
            try {
                 output = connection.getOutputStream();
                 output.write(payload);
            }
            finally {
                 if (output != null) {
                    try { output.close(); } catch (IOException logOrIgnore) {}
                }
            }

            InputStream in = connection.getInputStream();
            byte[] buff = readData(in);
            out.write(buff);

            List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
            keepCookies(request, cookies);
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
    }
    
    private HttpURLConnection getConnection(HttpServletRequest request, String url) throws IOException {
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
        connection.setRequestProperty("User-Agent", USER_AGENT);
        if(HTTP_REFERER != null) {
            connection.setRequestProperty("Referer", HTTP_REFERER);
        }
        setCookies(request, connection);

        return connection;
    }
    
    private void keepCookies(HttpServletRequest request, List<String> newCookies) {
        List<String> alCookies = (List<String>) request.getSession().getAttribute(COOKIES_IN_SESSION);
        if(alCookies == null) {
            alCookies = new ArrayList<String>();
            request.getSession().setAttribute(COOKIES_IN_SESSION, alCookies);
        }

        for (String cookie : newCookies) {
            String c = cookie.split(";", 2)[0];
            if(!alCookies.contains(c)) {
                alCookies.add(c);
            }
        }
        System.out.println(alCookies);
    }
    
    private void setCookies(HttpServletRequest request, HttpURLConnection connection) {
        List<String> alCookies = (List<String>) request.getSession().getAttribute(COOKIES_IN_SESSION);
        if(alCookies != null) {
            for (String cookie : alCookies) {
                connection.addRequestProperty("Cookie", cookie);
            }
        }
    }
    
    protected String replace(final String _str, final String _strOld, final String _strNew) {
        if(_str == null || _strOld == null || _strNew == null || _str.indexOf(_strOld) == -1) {
            return _str;
        }
        StringBuffer sb = new StringBuffer(_str);
        int iIndex = 0;
        while((iIndex = sb.indexOf(_strOld,iIndex)) != -1) {
            sb = sb.replace(iIndex,iIndex+_strOld.length(),_strNew);
            iIndex += _strNew.length();
        }
        
        return sb.toString();
    }

    protected byte[] readData(final InputStream in) throws java.io.IOException {
        final ByteArrayOutputStream baOut = new ByteArrayOutputStream();
        int nByte = 0;
        final byte[] buff = new byte[1024*1024];
        while((nByte = in.read(buff)) > 0) {
            baOut.write(buff,0, nByte);
        }
        final byte[] data = baOut.toByteArray();
        baOut.close();
        
        return data;
    }
}
